package com.wgz.medicalmanagement.controller;

import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.List;

import jakarta.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.wgz.medicalmanagement.common.entity.Result;
import com.wgz.medicalmanagement.domain.dto.PatientDTO;
import com.wgz.medicalmanagement.domain.dto.PatientQueryDTO;
import com.wgz.medicalmanagement.service.PatientService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

/**
 * 患者管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/patients")
@Tag(name = "患者管理接口", description = "提供患者的增删改查功能")
public class PatientController {

    @Autowired
    private PatientService patientService;

    /**
     * 获取患者列表
     * 
     * @param queryDTO 查询条件
     * @return 患者列表
     */
    @GetMapping
    @Operation(summary = "获取患者列表", description = "根据条件查询患者列表，支持分页")
    @PreAuthorize("hasAnyAuthority('PATIENT_VIEW', 'ADMIN')")
    public Result<Page<PatientDTO>> getPatientList(PatientQueryDTO queryDTO) {
        log.info("获取患者列表, 查询条件: {}", queryDTO);
        Page<PatientDTO> patientList = patientService.getPatientList(queryDTO);
        return Result.success("获取患者列表成功", patientList);
    }

    /**
     * 获取患者详情
     * 
     * @param id 患者ID
     * @return 患者详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取患者详情", description = "根据患者ID获取患者详细信息")
    @PreAuthorize("hasAnyAuthority('PATIENT_VIEW', 'ADMIN')")
    public Result<PatientDTO> getPatientDetail(@PathVariable Long id) {
        log.info("获取患者详情, id: {}", id);
        PatientDTO patient = patientService.getPatientDetail(id);
        return Result.success("获取患者详情成功", patient);
    }

    /**
     * 添加患者
     * 
     * @param patientDTO 患者信息
     * @return 添加结果
     */
    @PostMapping
    @Operation(summary = "添加患者", description = "添加新患者信息")
    @PreAuthorize("hasAnyAuthority('PATIENT_ADD', 'ADMIN')")
    public Result<PatientDTO> addPatient(@Validated @RequestBody PatientDTO patientDTO) {
        log.info("添加患者, 患者信息: {}", patientDTO);
        PatientDTO patient = patientService.addPatient(patientDTO);
        return Result.success("添加患者成功", patient);
    }

    /**
     * 更新患者信息
     * 
     * @param id 患者ID
     * @param patientDTO 患者信息
     * @return 更新结果
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新患者信息", description = "根据患者ID更新患者信息")
    @PreAuthorize("hasAnyAuthority('PATIENT_EDIT', 'ADMIN')")
    public Result<PatientDTO> updatePatient(@PathVariable Long id, @Validated @RequestBody PatientDTO patientDTO) {
        log.info("更新患者信息, id: {}, 患者信息: {}", id, patientDTO);
        PatientDTO patient = patientService.updatePatient(id, patientDTO);
        return Result.success("更新患者信息成功", patient);
    }

    /**
     * 删除患者
     * 
     * @param id 患者ID
     * @return 删除结果
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除患者", description = "根据患者ID删除患者")
    @PreAuthorize("hasAnyAuthority('PATIENT_DELETE', 'ADMIN')")
    public Result<Void> deletePatient(@PathVariable Long id) {
        log.info("删除患者, id: {}", id);
        patientService.deletePatient(id);
        return Result.success("删除患者成功", null);
    }
    
    /**
     * 导出患者数据
     * 
     * @param response HTTP响应对象
     * @param queryDTO 查询参数
     * @throws IOException 导出过程中可能发生的IO异常
     */
    @GetMapping("/export")
    @Operation(summary = "导出患者数据", description = "将患者数据导出为Excel文件")
    @PreAuthorize("hasAnyAuthority('PATIENT_VIEW', 'ADMIN')")
    public void exportPatients(HttpServletResponse response, PatientQueryDTO queryDTO) throws IOException {
        log.info("导出患者数据, 查询条件: {}", queryDTO);
        
        // 设置响应头信息
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("患者数据", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        
        // 获取患者数据
        if (queryDTO.getPage() != null) {
            queryDTO.setPage(0); // 从第一页开始
        }
        if (queryDTO.getSize() != null) {
            queryDTO.setSize(Integer.MAX_VALUE); // 获取所有数据
        }
        Page<PatientDTO> patientPage = patientService.getPatientList(queryDTO);
        List<PatientDTO> patientList = patientPage.getContent();
        
        // 创建Excel工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("患者数据");
        
        // 创建表头
        Row headerRow = sheet.createRow(0);
        String[] headers = {"ID", "姓名", "性别", "年龄", "联系电话", "身份证号", "地址", "病史", "过敏史", "创建时间", "更新时间"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }
        
        // 填充数据
        int rowIndex = 1;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (PatientDTO patient : patientList) {
            Row dataRow = sheet.createRow(rowIndex++);
            dataRow.createCell(0).setCellValue(patient.getId() != null ? patient.getId() : 0);
            dataRow.createCell(1).setCellValue(patient.getName() != null ? patient.getName() : "");
            dataRow.createCell(2).setCellValue(patient.getGender() != null ? patient.getGender() : "");
            dataRow.createCell(3).setCellValue(patient.getAge() != null ? patient.getAge() : 0);
            dataRow.createCell(4).setCellValue(patient.getPhone() != null ? patient.getPhone() : "");
            dataRow.createCell(5).setCellValue(patient.getIdCard() != null ? patient.getIdCard() : "");
            dataRow.createCell(6).setCellValue(patient.getAddress() != null ? patient.getAddress() : "");
            dataRow.createCell(7).setCellValue(patient.getMedicalHistory() != null ? patient.getMedicalHistory() : "");
            dataRow.createCell(8).setCellValue(patient.getAllergies() != null ? patient.getAllergies() : "");
            
            String createdTime = patient.getCreatedTime() != null ? sdf.format(patient.getCreatedTime()) : "";
            dataRow.createCell(9).setCellValue(createdTime);
            
            String updatedTime = patient.getUpdatedTime() != null ? sdf.format(patient.getUpdatedTime()) : "";
            dataRow.createCell(10).setCellValue(updatedTime);
        }
        
        // 设置列宽自适应
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }
        
        // 写入响应输出流
        workbook.write(response.getOutputStream());
        workbook.close();
    }
} 